﻿using IPC.Communication;
using IPC.Communication.Core.Types;
using IPC.ListConnect.ListProprety;
using IPC.ListConnect.Profinet;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IPC.ListConnect.Connect
{
    /// <summary>
    /// 所有连接集合
    /// </summary>
    public class ConnectList
    {

        private static ConnectList? _instance;
        public static ConnectList Instance
        {
            get
            {
                if(_instance == null)
                {
                    _instance = new ConnectList();
                }
                return _instance;
            }
            set
            {
                _instance = value;
            }
        }

        public ConnectList() 
        {
            foreach(var item in EquipChannels.Instance.EquipChannelList)
            {
                AddEquip(item, (ChannelType)(Enum.Parse(typeof(ChannelType), item.ChannelType)));
            }
        }

        private Dictionary<string, BaseConnect>  Connects = new Dictionary<string, BaseConnect>();

        #region 添加设备
        /// <summary>
        /// 添加设备
        /// </summary>
        /// <param name="equipChannel"></param>
        private void AddEquip(EquipChannel equipChannel, ChannelType channelType)
        {
            foreach (var item in equipChannel.Equips.Values)
            {
                string ip = item.Ip;
                string port = item.Port;
                string slot = item.Slot;
                string rack = item.Rack;
                string name = item.Name;
                string channelName = equipChannel.ChannelName;
                name = channelName + "." + name;
                BaseConnect connect = null;
                switch (channelType)
                {
                    case ChannelType.None:
                        break;
                    case ChannelType.ModbusTcp:
                        break;
                    case ChannelType.ModbusUdp:
                        break;
                    case ChannelType.Siemens:
                        connect = new SiemensConnect(name, ip, int.Parse(port), int.Parse(slot), int.Parse(rack), (SiemensVersion)Enum.Parse(typeof(SiemensVersion),item.Type));
                        break;
                    case ChannelType.AllenBradley:
                        connect = new AllenBradleyConnect(name, ip, int.Parse(port), int.Parse(slot), int.Parse(rack));
                        break;
                    case ChannelType.Virtual:
                        connect = new VirtualConnect(name, ip, int.Parse(port), int.Parse(slot), int.Parse(rack));
                        break;
                }

                if(connect != null)
                {
                    Connects.Add(name, connect);
                }
            }
        }
        #endregion

        #region 读
        /// <summary>
        /// 按组读
        /// </summary>
        /// <param name="equipChannel">通道名</param>
        /// <param name="equip">设备名</param>
        /// <param name="group">组名</param>
        //public OperateResult Read(string channelName, string equip, string group = "")
        //{
        //    //string equipFullName = channelName + "." + equip;
        //    //OperateResult operateResult = new OperateResult();
        //    //operateResult.IsSuccess = false;
        //    //operateResult.Message = "未找到设备";
        //    //if (Connects.ContainsKey(equipFullName))
        //    //{
        //    //    operateResult = Connects[equipFullName].Read();
        //    //}
        //    //return operateResult;
        //}

        /// <summary>
        /// 单点读
        /// </summary>
        /// <param name="channelName">通道名</param>
        /// <param name="equipName">设备名</param>
        /// <param name="tagName">标签名</param>
        /// <param name="groupName">组名</param>
        public OperateResult Read(string channelName, string equipName, string tagName, string groupName = "")
        {
            string equipFullName = channelName + "." + equipName;
            OperateResult operateResult = new OperateResult();
            operateResult.IsSuccess = false;
            operateResult.Message = "未找到设备";
            if (Connects.ContainsKey(equipFullName))
            {
                operateResult = Connects[equipFullName].Read(channelName, equipName, tagName, groupName);
            }
            return operateResult;
        }

        /// <summary>
        /// 按组读 返回json
        /// </summary>
        /// <param name="channelName"></param>
        /// <param name="equip"></param>
        /// <param name="group"></param>
        /// <returns></returns>
        public string ReadJson(string channelName, string equip, string group = "")
        {
            string equipFullName = channelName + "." + equip;
            OperateResult operateResult = new OperateResult();
            ReadResult readResult = new ReadResult();
            readResult.IsSuccess = false;
            readResult.Message = "未找到设备";
            string json = JsonConvert.SerializeObject(readResult);
            if (Connects.ContainsKey(equipFullName))
            {
                json = Connects[equipFullName].ReadJson(channelName, equip, group);
            }
            return json;
        }

        /// <summary>
        /// 单点读 返回json
        /// </summary>
        /// <param name="channelName"></param>
        /// <param name="equipName"></param>
        /// <param name="tagName"></param>
        /// <param name="groupName"></param>
        /// <returns></returns>
        public string ReadJson(string channelName, string equipName, string tagName, string groupName = "")
        {
            string equipFullName = channelName + "." + equipName;
            OperateResult operateResult = new OperateResult();
            ReadResult readResult = new ReadResult();
            readResult.IsSuccess = false;
            readResult.Message = "未找到设备";
            string json = JsonConvert.SerializeObject(readResult);
            if (Connects.ContainsKey(equipFullName))
            {
                json = Connects[equipFullName].ReadJson(channelName, equipName, tagName, groupName);
            }
            return json;
        }

        #endregion

        #region 写

        #region 多标签写
        /// <summary>
        /// 多标签写
        /// </summary>
        /// <param name="channelName">通道名</param>
        /// <param name="equipName">设备名</param>
        /// <param name="values">值</param>
        /// <param name="startTag">开始点</param>
        /// <param name="groupName">组名</param>
        /// <returns></returns>
        public OperateResult Write(string channelName, string equipName, string[] values, string startTag = "", string groupName = "")
        {
            string equipFullName = channelName + "." + equipName;
            OperateResult operateResult = new OperateResult();
            operateResult.IsSuccess = false;
            operateResult.Message = "未找到设备";
            if (Connects.ContainsKey(equipFullName))
            {
                operateResult = Connects[equipFullName].Write(channelName, equipName, values, startTag, groupName);
            }
            return operateResult;
        }
        #endregion

        #region 单标签写
        /// <summary>
        /// 单标签写
        /// </summary>
        /// <param name="channelName">通道名</param>
        /// <param name="equipName">设备名</param>
        /// <param name="tagName">标签名</param>
        /// <param name="values">值</param>
        /// <param name="groupName">组名</param>
        /// <returns></returns>
        public OperateResult Write(string channelName, string equipName, string tagName, string values, string groupName = "")
        {
            string equipFullName = channelName + "." + equipName;
            OperateResult operateResult = new OperateResult();
            operateResult.IsSuccess = false;
            operateResult.Message = "未找到设备";
            if (Connects.ContainsKey(equipFullName))
            {
                operateResult = Connects[equipFullName].Write(channelName, equipName, tagName, values, groupName);
            }
            return operateResult;
        }
        #endregion

        #region 多标签写 返回json
        /// <summary>
        /// 多标签写 返回json
        /// </summary>
        /// <param name="channelName">通道名</param>
        /// <param name="equipName">设备名</param>
        /// <param name="json">值的json格式 格式为["test1","test2"]</param>
        /// <param name="startTag">开始点</param>
        /// <param name="groupName">组名</param>
        /// <returns></returns>
        public string WriteByJson(string channelName, string equipName, string json, string startTag = "", string groupName = "")
        {
            string equipFullName = channelName + "." + equipName;
            OperateResult operateResult = new OperateResult();
            operateResult.IsSuccess = false;
            operateResult.Message = "未找到设备";
            ReadResult readResult = new ReadResult();
            readResult.IsSuccess = false;
            readResult.Message = "未找到设备";
            List<string> list = new List<string>();
            try
            {
                list = (List<string>)JsonConvert.DeserializeObject(json, typeof(List<string>));
            }
            catch (Exception ex)
            {
                readResult.IsSuccess = false;
                readResult.Message = "数据转换失败。请检查json格式是否为:[\"test1\",\"test2\"]";
                return JsonConvert.SerializeObject(readResult);
            }
            string[] values = new string[list.Count];
            for (int i = 0; i < list.Count; i++)
            {
                values[i] = list[i];
            }
            if (Connects.ContainsKey(equipFullName))
            {
                operateResult = Connects[equipFullName].Write(channelName, equipName, values, startTag, groupName);
                readResult.IsSuccess = operateResult.IsSuccess;
                readResult.Message = operateResult.Message;
            }
            return JsonConvert.SerializeObject(readResult);
        }
        #endregion

        #region 单标签写 返回json
        /// <summary>
        /// 单标签写 返回json
        /// </summary>
        /// <param name="channelName">通道名</param>
        /// <param name="equipName">设备名</param>
        /// <param name="tagName">标签名</param>
        /// <param name="values">值</param>
        /// <param name="groupName">组名</param>
        /// <returns></returns>
        public string WriteJson(string channelName, string equipName, string tagName, string values, string groupName = "")
        {
            string equipFullName = channelName + "." + equipName;
            OperateResult operateResult = new OperateResult();
            operateResult.IsSuccess = false;
            operateResult.Message = "未找到设备";
            ReadResult readResult = new ReadResult();
            readResult.IsSuccess = false;
            readResult.Message = "未找到设备";
            if (Connects.ContainsKey(equipFullName))
            {
                operateResult = Connects[equipFullName].Write(channelName, equipName, tagName, values, groupName);
                readResult.IsSuccess = operateResult.IsSuccess;
                readResult.Message = operateResult.Message;
            }
            return JsonConvert.SerializeObject(readResult);
        } 
        #endregion
        #endregion
    }
}
